#ifndef _HTTPIMPL_H_
#define _HTTPIMPL_H_

#include "stdafx.h"
#include "http_protocol/chttpparser.h"

class CHttpIImpl : public IHttp, public IOperationProc, public IDnsProc, public CUnknownImp, public CHttpParser
{
public:
    CHttpIImpl();
    virtual ~CHttpIImpl(void);

public:
    BEGIN_STDCOM_MAP
    STDCOM_INTERFACE_ENTRY_UNKNOWN_(IHttp)
    STDCOM_INTERFACE_ENTRY(IHttp)
    STDCOM_INTERFACE_ENTRY(IDnsProc)
    STDCOM_INTERFACE_ENTRY(IOperationProc);
    END_STDCOM_MAP

public:
    HRESULT init_class(const _lComPtr<IAsynFrame>& AsynFrame, const _lComPtr<INetFrame>& Net);

public:
    // IHttp
    std_method(BindEvent)(IBase* pBase);
    std_method(UnBindEvent)();
    std_method(SetCookies)(http_header* data);
    std_method(Open)(SafeStringPtr addr, SafeStringPtr scheme, unsigned short port);
    std_method_(http_header, GetHttpHead)();
    std_method(ReSet)();
    std_method(Cancel)();
    std_method_(int, IsComplete)();

    // IIoOperationEvents
    std_method(OnComplete)(IBase* pOperation, crtid cid, crterr err);

    // IDnsProc
    std_method(OnGetHost)(crterr error, const char* url, const char* ip);

private:
    ULONG OnNotify(crtid cid, crterr err);
    ULONG Id_Suc(ULONG ulid);
    ULONG Id_Faild(ULONG ulid);

private:
    HRESULT httpEventProc(crtid cid, IBase* pOperation);
    HRESULT httpConnected(IBase* pBase);
    HRESULT httpSendHeaded(IBase* pBase);
    HRESULT httpSendBodyed(IBase* pBase);
    HRESULT httpRecvHeaded(IBase* pBase);
    HRESULT httpRecvBodyed(IBase* pBase);
    HRESULT httpEvent(crtid event, IBase* pSocket, IBase* pOperation);

private:
    HRESULT httpConnect(IOperation* pOperation, NET_ADDR addr, NET_PORT uport);
    HRESULT httpSendHead(IBase* pSocket, IBase* pOperation);
    HRESULT httpSendBody(IBase* pSocket, IBase* pOperation);
    HRESULT httpRecvHead(IBase* pSocket, IBase* pOperation);
    HRESULT httpRecvBody(IBase* pSocket, IBase* pOperation);
    HRESULT httpSend(crtid cid, IBase* pSocket, IBase* pOperation);
    HRESULT httpRecv(crtid cid, IBase* pSocket, IBase* pOperation);

private:
    void on_http_message_begin();
    void on_http_header_complete();
    void on_http_body(const char* at, size_t length);
    void on_http_message_complete();

private:
    HRESULT OnConnect(NET_ADDR addr, ULONG addrlen);
    HRESULT OnBuildHttp(http_addr_s url, http_addr_s scheme, NET_PORT uport);

private:
    _lComPtr<IDns> m_pIDns;
    int64 m_httpcontent_length;
    CharArrayPtr m_szhttpHead;
    CharArrayPtr m_szhttpSendHead;
    CharArrayPtr m_szhttpurl;

    NET_PORT m_uport;
    _lComPtr<IHttpProc> m_pHandle;
    http_header_t m_http_resheader;
    long m_hstid;

    varaint_t m_varurl;
    varaint_t m_varschema;
};

#endif
